Today's microcontroller (MCU) employs vertical integration design techniques to provide highly sophisticated, on-chip peripheral capabilities (e.g. timer, serial communications interface). Typically, a central processing unit (CPU) in the microcontroller sequentially executes a set of instructions in response to requests (interrupts) from these on-chip peripheral devices. Some of these on-chip peripherals are real-time devices, which run asynchronously to the execution of the main program. Thus, the CPU can not predict exactly when these real-time peripherals will require servicing. It is necessary, therefore, to employ an interrupt system to allow the CPU to temporarily suspend normal program execution, and service the incoming requests from the on-chip peripheral. Generally, the interrupt system incorporates several prioritized interrupt levels which govern the order in which the CPU responds to the interrupt request. In response to a higher priority interrupt request, the CPU branches to an interrupt service routine, and commences execution of the sequence of instructions which comprise the service routine. Upon completion of the interrupt service routine, the CPU resumes normal program execution.
Generally, in low and mid-range microcontrollers, which do not support interrupt vector numbers, the CPU time required to service interrupts generated by on-chip peripherals creates a performance problem. The addition of on-chip peripheral capabilities may increase the overall performance of the MCU; however, for some MCUs these peripherals may incur too much processor (CPU) overhead to service interrupts. In known systems, the CPU typically performs three actions upon the occurrence of an interrupt. Initially, the CPU determines the specific cause of the interrupt. Secondly, the CPU determines what action to take, and thirdly the CPU performs the required action, which is usually a jump to the interrupt service routine. Generally, these three actions are time consuming, and must be performed for each interrupt.
In existing systems, such as the Motorola MC68HC11 MCU, the interrupt service routines are called through automatic hardware interrupt mechanisms. In response to an interrupt, the CPU suspends normal program execution, after finishing the currently executing instruction. Interrupt logic circuitry then pushes the contents of all of the CPU registers onto a stack, thereby insuring that the CPU context can be restored after the CPU finishes the interrupt service routine. After stacking the CPU registers, the vector for the highest priority pending interrupt source is loaded into the program counter (PC), and the CPU commences to execute the first instruction of the interrupt service routine. Essentially, the CPU must evaluate all pending interrupts to determine which source has the highest priority, after the contents of the CPU registers are pushed onto the stack.
Shown in FIG. 1 is a flow diagram 10 illustrating a known technique for processing interrupts. Typically, the CPU fetches and decodes instructions in accordance with a program sequence. Upon completion of the instructions execution, the CPU checks to see if an interrupt request occurred. Generally, each of the on-chip interrupt sources (e.g. peripherals) has a flag bit which indicates service is required, and an enable bit which enables the flag to generate hardware interrupt requests. The CPU reads the flag bits in priority order, thereby ascertaining the source of the interrupt, and retrieves the current state information (for the interrupt-generating peripheral) from a random access memory (RAM) device. Using the current state information, the CPU calculates the address for the corresponding interrupt service routine, and branches to the service routine. The current state of the interrupt-generating peripheral is saved in a location in RAM, and subsequently updated, by the CPU, with the next state information. The CPU proceeds to execute the interrupt service routine. Typically, the interrupt service routine terminates with a return from interrupt (RTI) instruction, which allows all CPU registers, and the return address, to be recovered from the stack. The CPU resumes execution of the interrupted program, as if no interrupt had occurred.
In many cases, the programmer uses a software state machine to redundantly mirror the action taken by the hardware state machine of the interrupt-generating peripheral. Duplication of the peripheral state machine in software wastes RAM space, and processor time. Consequently, the servicing of interrupts causes a significant burden on the overall system performance. Thus, it is desirable to provide an interrupt mechanism capable of overcoming the foregoing problems.